#
# Ronin Exploits - A Ruby library for Ronin that provides exploitation and
# payload crafting functionality.
#
# Copyright (c) 2007-2013 Hal Brodigan (postmodern.mod3 at gmail.com)
#
# This file is part of Ronin Exploits.
#
# Ronin is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Ronin is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ronin.  If not, see <http://www.gnu.org/licenses/>
#

require 'ronin/model'
require 'ronin/software'

module Ronin
  module Model
    #
    # Adds a `software` relation between the model and the `Ronin::Software`
    # model.
    #
    module TargetsSoftware
      def self.included(base)
        base.send :include, InstanceMethods
        base.send :extend, ClassMethods

        base.module_eval do
          # The targeted software
          belongs_to :software,
                     model: 'Ronin::Software',
                     required: false
        end

        Software.has Software.n, base.relationship_name, model: base.name
      end

      module ClassMethods
        #
        # Queries all resources targeting a specific Software.
        #
        # @param [Software, Hash, #to_s] software
        #   The software to search for.
        #
        # @param [String] version
        #   Optional version to search for.
        #
        # @return [DataMapper::Collection]
        #   The matching resources.
        #
        # @since 1.0.0
        #
        # @api public
        #
        def targeting_software(software,version=nil)
          conditions = case software
                       when Software, Hash
                         {software: software}
                       else
                         {'software.name.like' => "%#{software}%"}
                       end

          if version
            conditions['software.version'] = version
          end

          all(conditions)
        end
      end

      module InstanceMethods
        #
        # Targets a piece of software.
        #
        # @param [String] name
        #   The name for the targeted software.
        #
        # @param [String] version
        #   The version for the targeted software.
        #
        # @return [Software]
        #   The piece of software that is being targeted.
        #
        # @example
        #   t.targets_software 'Apache', '1.3.3.7'
        #   # => #<Ronin::Software @id=nil @name="Apache" @version="1.3.3.7">
        #
        # @since 1.0.0
        #
        def targets_software(name,version=nil)
          self.software = Software.first_or_new(
            name:    name,
            version: version
          )
        end
      end
    end
  end
end
